package co.bugu.code.analysis.application.task;

import co.bugu.code.analysis.application.service.ProjectService;
import co.bugu.code.analysis.infra.entity.Branch;
import co.bugu.code.analysis.infra.entity.Commit;
import co.bugu.code.analysis.infra.repo.BranchRepo;
import co.bugu.code.analysis.infra.repo.CommitRepo;
import co.bugu.code.analysis.infra.repo.ProjectRepo;
import co.bugu.framework.db.search.CommonSeg;
import co.bugu.framework.db.search.Condition;
import co.bugu.framework.db.search.Operator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author daocers
 * @date 2025/5/26 15:29
 */
@Service
@Slf4j
public class SyncTask {
    @Autowired
    ProjectRepo projectRepo;
    @Autowired
    BranchRepo branchRepo;

    @Autowired
    CommitRepo commitRepo;

    @Autowired
    ProjectService projectService;

    @Scheduled(initialDelay = 1000 * 30, fixedDelay = 1000 * 60 * 60)
    public void fetchProject() {
        try {
            projectService.fetchDeltaProject();
        } catch (Exception e) {
            log.error("获取工程失败", e);
        }
    }


    @Scheduled(initialDelay = 1000 * 30, fixedDelay = 1000 * 60)
    public void fetchBranch() {

        try {
            Date begin = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L * 7);
            Date end = new Date();
            CommonSeg commonSeg = CommonSeg.AND().add(Condition.of("last_activity_at", Operator.GREATER_THEN, begin));
            int pageNum = 1;
            int pageSize = 100;
            List<co.bugu.code.analysis.infra.entity.Project> projects = new ArrayList<>();
            do {
                projects = projectRepo.search(pageNum, pageSize, commonSeg, "last_activity_at");
                if (CollectionUtils.isEmpty(projects)) {
                    break;
                }
                pageNum++;

                for (co.bugu.code.analysis.infra.entity.Project projectInDB : projects) {
                    try {
                        projectService.fetchDeltaBranch(projectInDB.getProjectId(), begin, end);
                    } catch (Exception e) {
                        log.error("获取项目 {} 分支失败", projectInDB.getPathWithNamespace(), e);
                    }
                }
            } while (pageSize == projects.size());
        } catch (Exception e) {
            log.error("获取分支失败", e);
        }
    }


    @Scheduled(initialDelay = 1000 * 30, fixedDelay = 1000L * 60 * 5)
    public void fetchCommit() {
        try {
            int pageNum = 1;
            int pageSize = 100;
            List<Branch> branches;
            do {
                CommonSeg commonSeg = CommonSeg.AND().add(Condition.of("latest_commit_time", Operator.GREATER_THEN, new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 7)));
                branches = branchRepo.search(pageNum, pageSize, commonSeg);
                if (CollectionUtils.isEmpty(branches)) {
                    break;
                }
                for (Branch branch : branches) {
                    projectService.fetchDeltaCommitsWithBranchInfo(branch.getProjectId(), branch.getId(), branch.getName(), new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 7), new Date());
                }
                pageNum++;
            } while (branches.size() == pageSize);

        } catch (Exception e) {
            log.error("获取提交失败", e);
        }
    }


    /**
     * 拉取用户信息
     * 2小时执行一次，
     *
     * @param
     * @return
     * @author alei
     * @date 2025/5/30 9:15
     */
    @Scheduled(initialDelay = 1000 * 10, fixedDelay = 1000 * 60 * 60 * 2)
    public void fetchUser() {
        try {
            projectService.fetchDeltaUser(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L * 14), new Date());
        } catch (Exception e) {
            log.error("获取用户失败", e);
        }
    }


    //    @Scheduled(initialDelay = 1000 * 10, fixedDelay = 1000 * 60 * 60 * 2)
    public void init() {
        List<co.bugu.code.analysis.infra.entity.Project> projects = projectService.fetchAllProject();
        log.info("获取到项目信息：数量{}", projects.size());
        if (CollectionUtils.isNotEmpty(projects)) {
            projects.stream().forEach(project -> {
                log.info("开始处理项目：{} ", project.getPathWithNamespace());
                List<co.bugu.code.analysis.infra.entity.Branch> branches = projectService.fetchAllBranch(project.getId());
                log.info("共有分支：{}", branches.size());
                if (CollectionUtils.isNotEmpty(branches)) {
                    branches.stream().forEach(branch -> {
                        log.info("开始处理分支：{}", branch.getName());
                        List<co.bugu.code.analysis.infra.entity.Commit> commits = projectService.fetchAllCommit(project.getId(), branch.getId(), branch.getName());
                        log.info("分支{} 共有 {} 次commit", branch.getName(), commits.size());
//                        if(CollectionUtils.isNotEmpty(commits)){

//                            commits.stream().forEach(commit -> {
//                                List<co.bugu.code.analysis.infra.entity.Diff> diffs = projectService.getDiffByCommit(project.getId(), commit);
//                            });
//                        }
                    });
                }
            });
        }

    }

    ExecutorService executorService = Executors.newFixedThreadPool(8);


    //    @Scheduled(initialDelay = 1000 * 10, fixedDelay = 1000 * 60 * 10000)
    public void initCommit() {
        int pageNum = 1;
        int pageSize = 100;

        List<co.bugu.code.analysis.infra.entity.Branch> branches = new ArrayList<>();

        do {
            CommonSeg commonSeg = CommonSeg.AND().add(Condition.of("latest_commit_time", Operator.GREATER_THEN_EQUAL, "2024-01-01 00:00:00"));
            branches = branchRepo.search(pageNum, pageSize, commonSeg, "id");

            for (co.bugu.code.analysis.infra.entity.Branch branch : branches) {
                if (branch.getMerged() == 1) {
                    continue;
                }
                executorService.execute(new Runnable() {

                    @Override
                    public void run() {
                        log.info("开始处理分支：{}", branch.getName());
                        List<co.bugu.code.analysis.infra.entity.Commit> commits = projectService.fetchAllCommit(branch.getProjectId(), branch.getId(), branch.getName());
                        log.info("分支{} 共有 {} 次commit", branch.getName(), commits.size());
                        if (CollectionUtils.isNotEmpty(commits)) {

//                            commits.stream().forEach(commit -> {
//                                List<co.bugu.code.analysis.infra.entity.Diff> diffs = projectService.getDiffByCommit(branch.getProjectId(), commit);
//                            });
                        }
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                });

            }

            pageNum++;
        } while (branches.size() == pageSize);
    }


    //    @Scheduled(initialDelay = 1000 * 10, fixedDelay = 1000 * 60 * 10000)
    public void initDiff() {
        int pageNum = 1;
        int pageSize = 100;

        Long id = 0L;
        List<co.bugu.code.analysis.infra.entity.Commit> commitList = new ArrayList<>();

        do {
            CommonSeg commonSeg = CommonSeg.AND().add(Condition.of("id", Operator.GREATER_THEN, id));
            commitList = commitRepo.search(pageNum, pageSize, commonSeg, "id");

            for (Commit commit : commitList) {
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        log.info("开始处理 project:{}, branch: {},commit：{}", commit.getProjectId(), commit.getBranchName(), commit.getCommitId());
                        List<co.bugu.code.analysis.infra.entity.Diff> diffs = projectService.getDiffByCommit(commit.getProjectId(), commit);

                    }
                });
            }
            id = commitList.get(commitList.size() - 1).getId();

        } while (commitList.size() == pageSize);
    }

}
